package net.uman.test;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;

import net.uman.util.Constants;

/**
 * UserDao的测试用例, 测试ORM映射及特殊的DAO操作.
 * 
 * 默认在每个测试函数后进行回滚.
 * 
 * @author calvin
 */
public class DataGenerator {
	public final static int N_CATEGORY = 7;
	public final static int N_GOODS = 500000;
	public final static int N_TRADEGOODS = 500000;
	public final static int N_TRADEOBJECT = 50000000;
	public final static int N_LOGISTICS = 100;
	public final static int N_SUPPLIER = 1000;
	public final static int N_CHAINHQ = 100;
	public final static int N_BRAND = 1000;
	public final static int N_STORE = 50000;
	public final static int N_LCTOBJECT = 500000;
	public final static int N_LTCOVER = 500000;
	public final static int N_LTSTORE = 100000;
	public final static int N_SGOODSCATALOG = 500000;
	public final static int N_CGOODSCATALOG = 500000;
	public final static int N_CSTORESTOCK = 50000000;
	public final static int N_CHAINORDERPRICE = 1000;
	public final static int N_RETAILPRICE = 1000;
	public final static int N_STOREORDERPRICE = 1000;
	public final static int N_DELIVERYFEE = 500000;
	
	private static final String PATH = "C:/test/";
	
	public void createData() throws Exception {
		File file = new File(PATH);
		if (!file.exists()) {
			file.mkdirs();
		}
		createBrands("Brand.txt");		
		createCategories("Category.txt");
		createGoods("Goods.txt");
		createTradeGoods("TradeGoods.txt");
		createLogistics("Logistics.txt");
		createSuppliers("Suppliers.txt");
		createChainhq("Chainhq.txt");
		createStores("Stores.txt");
		createTradeObject("TradeObject.txt");
		createCGoodsCatalog("CGoodsCatalog.txt");
		createChainOrderPrice("ChainOrderPrice.txt");
		createCStoreStock("CStoreStock.txt");
		createDeliveryFee("DeliveryFee.txt");
		createLCTObject("LCTObject.txt");
		createLTCover("LTCover.txt");
		createLTStore("LTStore.txt");
		createRetailPrice("RetailPrice.txt");
		createSGoodsCatalog("SGoodsCatalog.txt");
		createStoreOrderPrice("StoreOrderPrice.txt");
	}
	
	private void createStores(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				for (int i = 1 ; i <= N_STORE ; i++) {
					writer.write("insert into chain_store(chain_store_id,chain_headquarters_id,CONNECTOR,name) values("+i+","+(i % N_CHAINHQ + 1)+",'张"+i+"','门店"+i+"');\n");
					if (i % 10000 == 0) {
						writer.write("commit;\n");
					}
				}
				writer.write("commit;\n");
			}
		});		
	}
	
	private void createChainhq(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				for (int i = 1 ; i <= N_CHAINHQ ; i++) {
					writer.write("insert into chain_headquarters(chain_headquarters_id,name,category_id)  values ("+i+",'物美"+i+"',"+(i % N_CATEGORY + 1)+");\n");
					if (i % 10000 == 0) {
						writer.write("commit;\n");
					}
				}
				writer.write("commit;\n");
			}
		});
	}
	
	private void createLogistics(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				for (int i = 1 ; i <= N_LOGISTICS ; i++) {
					writer.write("insert into logistics(logistics_id,name,category_id) values ("+i+",'配送"+i+"',"+(i % N_CATEGORY + 1)+");\n");
					if (i % 10000 == 0) {
						writer.write("commit;\n");
					}
				}
				writer.write("commit;\n");
			}
		});
	}
	
	private void createSuppliers(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				for (int i = 1 ; i <= N_SUPPLIER ; i++) {
					writer.write("insert into supplier(supplier_id,name,category_id) values("+i+",'供货商"+i+"',"+(i % N_CATEGORY + 1)+");\n");
					if (i % 10000 == 0) {
						writer.write("commit;\n");
					}
				}
				writer.write("commit;\n");
			}
		});
	}
	
	private void createTradeObject(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				for (int i = 1 ; i <= N_TRADEOBJECT ; i++) {
					writer.write("insert into trade_object(trade_object_id,trade_goods_id,supplier_id,chain_headquarters_id,`c_goods_catalog_id`,`chain_order_price_id`,`goods_name`,`b2b_code`,`status`,`sale_type`) "+
							"values ("+i+","+(i % N_TRADEGOODS + 1)+","+(i % N_SUPPLIER+1)+","+(i % N_CHAINHQ+1)+","+(i % N_CGOODSCATALOG+1)+","+(i % N_CHAINORDERPRICE+1)+",'NOKIA N"+i+"','B"+i+"',"+(i%2)+","+(i%3)+");\n");
					if (i % 10000 == 0) {
						writer.write("commit;\n");
					}
				}
				writer.write("commit;\n");
			}
		});
	}
	
	private void createTradeGoods(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				for (int i = 1 ; i <= N_TRADEGOODS ; i++) {
					writer.write("insert into trade_goods(trade_goods_id,goods_id,b2b_code,name,status,`category_id`) values("+i+","+i+",'B"+i+"','NOKIA N"+i+"',"+(i % 5)+","+(i % N_CATEGORY +1)+");\n");
					if (i % 10000 == 0) {
						writer.write("commit;\n");
					}
				}
				writer.write("commit;\n");
			}
		});
	}	
	
	private void createGoods(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				for (int i = 1 ; i <= N_GOODS ; i++) {
					writer.write("insert into goods (`goods_id`,`deleted`,`market_price`,`goods_name`,`status`,`brand_id`,`category_id`) "+
							"values("+i+",false,1000,'NOKIA N"+i+"',0,"+(i % N_BRAND + 1)+","+(i % N_CATEGORY +1)+");\n");
					if (i % 10000 == 0) {
						writer.write("commit;\n");
					}
				}
				writer.write("commit;\n");
			}
		});
	}

	private void createBrands(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				for (int i = 1 ; i <= N_BRAND ; i++) {
					writer.write("insert into `brand` (`brand_id`,`name`,`logo`,`description`,`site_url`,`sort_order`,`is_show`  ) values ("+i+",'诺基亚"+i+"','images/100727/nokia.gif','官方咨询电话：4008800123售后网点：http://www.nokia.com.cn/A4630632','http://www.nokia.com.cn',1,true);\n");
					if (i % 10000 == 0) {
						writer.write("commit;\n");
					}
				}
				writer.write("commit;\n");
			}
		});
	}

	private void createCategories(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				writer.write("insert into category(`category_id`,`cate_order`,`description`,`filter_attr`,`grade`,`is_show`,`keywords`,`measure_unit`,`name`,`show_in_nav`,`style`,`template_file`,`parent_id`)  values(1, 1, '','',true,true,'','','日用百货',true,'','',null);\n");
				writer.write("insert into category(`category_id`,`cate_order`,`description`,`filter_attr`,`grade`,`is_show`,`keywords`,`measure_unit`,`name`,`show_in_nav`,`style`,`template_file`,`parent_id`)  values(2, 1, '','',true,true,'','','电视',true,'','',null);\n");
				writer.write("insert into category(`category_id`,`cate_order`,`description`,`filter_attr`,`grade`,`is_show`,`keywords`,`measure_unit`,`name`,`show_in_nav`,`style`,`template_file`,`parent_id`)  values(3, 1, '','',true,true,'','','笔记本',true,'','',null);\n");
				writer.write("insert into category(`category_id`,`cate_order`,`description`,`filter_attr`,`grade`,`is_show`,`keywords`,`measure_unit`,`name`,`show_in_nav`,`style`,`template_file`,`parent_id`)  values(4, 1, '','',true,true,'','','手机',true,'','',null);\n");
				writer.write("insert into category(`category_id`,`cate_order`,`description`,`filter_attr`,`grade`,`is_show`,`keywords`,`measure_unit`,`name`,`show_in_nav`,`style`,`template_file`,`parent_id`)  values(5, 1, '','',true,true,'','','音乐手机',true,'','',4);\n");
				writer.write("insert into category(`category_id`,`cate_order`,`description`,`filter_attr`,`grade`,`is_show`,`keywords`,`measure_unit`,`name`,`show_in_nav`,`style`,`template_file`,`parent_id`)  values(6, 1, '','',true,true,'','','商务手机',true,'','',4);\n");
				writer.write("insert into category(`category_id`,`cate_order`,`description`,`filter_attr`,`grade`,`is_show`,`keywords`,`measure_unit`,`name`,`show_in_nav`,`style`,`template_file`,`parent_id`)  values(7, 1, '','',true,true,'','','照相机',true,'','',null);\n");
				writer.write("commit;\n");
			}
		});
	}
	
	private void createSGoodsCatalog(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				for (int i = 1 ; i <= N_SGOODSCATALOG ; i++) {
					writer.write("insert into s_goods_catalog(s_goods_catalog_id,s_goods_code,s_goods_name,trade_goods_id,supplier_id) values("+i+",'TB"+i+"','笔记本"+i+"',"+(i % N_TRADEGOODS + 1)+","+(i % N_SUPPLIER + 1)+");\n");
					if (i % 10000 == 0) {
						writer.write("commit;\n");
					}
				}
				writer.write("commit;\n");
			}
		});
	}

	private void createLCTObject(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				for (int i = 1 ; i <= N_LCTOBJECT ; i++) {
					writer.write("insert into l_c_t_object(l_c_t_object_id,`supplier_id`,`chain_headquarters_id`,`logistics_id`,`l_t_cover_id`,`delivery_object_type`,`delivery_object_id`) "+
							"values("+i+","+(i % N_SUPPLIER + 1)+","+(i % N_CHAINHQ + 1)+","+(i % N_LOGISTICS + 1)+","+(i % N_LTCOVER + 1)+","+(i % 2)+","+(i%2==0 ? (i % N_CHAINHQ + 1) : (i % N_TRADEOBJECT + 1))+");\n");
					if (i % 10000 == 0) {
						writer.write("commit;\n");
					}
				}
				writer.write("commit;\n");
			}
		});
	}

	private void createLTStore(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				for (int i = 1 ; i <= N_LTSTORE ; i++) {
					writer.write("insert into l_t_store(l_t_store_id,l_t_cover_id,chain_store_id,logistics_id) values("+i+","+(i % N_LTCOVER + 1)+","+(i % N_STORE + 1)+","+(i % N_LOGISTICS + 1)+");\n");
					if (i % 10000 == 0) {
						writer.write("commit;\n");
					}
				}
				writer.write("commit;\n");
			}
		});
	}

	private void createCGoodsCatalog(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				for (int i = 1 ; i <= N_CGOODSCATALOG ; i++) {
					writer.write("INSERT INTO `c_goods_catalog` (`c_goods_catalog_id`, `status`, `chain_headquarters_id`, `trade_goods_id`, `b2b_code`) "+
							"VALUES ("+i+",1,"+(i % N_CHAINHQ + 1)+","+(i % N_TRADEGOODS + 1)+",'B"+i+"');\n");
					if (i % 10000 == 0) {
						writer.write("commit;\n");
					}
				}
				writer.write("commit;\n");
			}
		});
	}
	
	private void createCStoreStock(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				for (int i = 1 ; i <= N_CSTORESTOCK ; i++) {
					writer.write("INSERT INTO `c_store_stock` (`c_store_stock_id`, `chain_store_id`, `c_goods_catalog_id`, `advice_stock`, `current_stock`) "+
								"VALUES("+i+","+(i % N_STORE + 1)+","+(i % N_CGOODSCATALOG + 1)+","+(i % 30)+",3);\n");
					if (i % 10000 == 0) {
						writer.write("commit;\n");
					}
				}
				writer.write("commit;\n");
			}
		});
	}

	private void createLTCover(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				for (int i = 1 ; i <= N_LTCOVER ; i++) {
					writer.write("INSERT INTO `l_t_cover` (`l_t_cover_id`,`logistics_id`,`chain_headquarters_id`,`cover_type`,`owner_type`,`supplier_id`) "+
						"VALUES("+i+","+(i % N_LOGISTICS + 1)+","+(i % N_CHAINHQ + 1)+","+(i % 3)+","+(i % 2)+","+(i % N_SUPPLIER + 1)+");\n");
					if (i % 10000 == 0) {
						writer.write("commit;\n");
					}
				}
				writer.write("commit;\n");
			}
		});
	}
	
	private void createDeliveryFee(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				for (int i = 1 ; i <= N_DELIVERYFEE ; i++) {
					writer.write("INSERT INTO `delivery_fee` (`delivery_fee_id`,`fee_type_id`,`lct_id`,`fee_type`,`return_delivery_fee`,`order_delivery_fee`) "+
						"VALUES("+i+","+(i%2==0 ? (i%N_LCTOBJECT + 1) : (i%N_TRADEOBJECT + 1))+","+(i % N_LCTOBJECT + 1)+","+(i%2)+","+(i%3)+","+(i%2)+");\n");
					if (i % 10000 == 0) {
						writer.write("commit;\n");
					}
				}
				writer.write("commit;\n");
			}
		});
	}

	private void createChainOrderPrice(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				for (int i = 1 ; i <= N_CHAINORDERPRICE ; i++) {
					writer.write("INSERT INTO `chain_order_price` (`chain_order_price_id`,`return_price`,`purchase_price`) VALUES("+i+","+(i % 1000)+","+(i % 800)+");\n");
					if (i % 10000 == 0) {
						writer.write("commit;\n");
					}
				}
				writer.write("commit;\n");
			}
		});
	}

	private void createRetailPrice(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				for (int i = 1 ; i <= N_RETAILPRICE ; i++) {
					writer.write("INSERT INTO `retail_price` (`retail_price_id`, `retail_price_type`, `source_id`, `c_goods_catalog_id`, `retail_price`) VALUES ("+i+","+(i % 2)+","+(i % 2 == 0 ? (i % N_CHAINHQ + 1) : (i % N_STORE + 1))+","+(i % N_CGOODSCATALOG + 1)+","+(i % 1000)+");\n");
					if (i % 10000 == 0) {
						writer.write("commit;\n");
					}
				}
				writer.write("commit;\n");
			}
		});
	}

	private void createStoreOrderPrice(String path) throws Exception {
		createData(path, new DataProvider() {
			public void writeData(Writer writer) throws IOException {
				for (int i = 1 ; i <= N_STOREORDERPRICE ; i++) {
					writer.write("INSERT INTO `store_order_price` (`store_order_price_id`, `store_order_price_type`, `source_id`, `order_price`, `return_price`, `c_goods_catalog_id`, `profit`, `member_profit`) "+
							"VALUES ("+i+","+(i % 2)+","+(i % 2 == 0 ? (i % N_CHAINHQ + 1) : (i % N_STORE + 1))+","+(i % 1000)+","+(i % 800)+","+(i % N_CGOODSCATALOG + 1)+",2,1);\n");
					if (i % 10000 == 0) {
						writer.write("commit;\n");
					}
				}
				writer.write("commit;\n");
			}
		});
	}

	private void createData(String path, DataProvider provider) throws Exception {
		System.out.println("Creating "+path+" ...");
		File file = new File(PATH + path);
		if (!file.exists()) {
			file.createNewFile();
		}
		BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true), "UTF-8"));
		
		provider.writeData(writer);

		writer.close();
	}
	
	interface DataProvider {
		void writeData(Writer writer) throws IOException;
	}
	
	public static void main(String[] args) {
		try {
			new DataGenerator().createData();
		} catch (Exception e) {
			e.printStackTrace();
		}
//		new DbInitTest().clearData();
		System.out.println("done");
	}
}